package com.wedimob.slideshare.task.cpu;

import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import com.google.gson.Gson;
import com.wedimob.slideshare.Factory;
import com.wedimob.slideshare.WriteType;
import com.wedimob.slideshare.bo.Medium;
import com.wedimob.slideshare.bo.MediumType;
import com.wedimob.slideshare.bo.SharedDocument;
import com.wedimob.slideshare.bo.Summary;
import com.wedimob.slideshare.task.PoolExecutor;
import com.wedimob.slideshare.task.Task;
import com.wedimob.slideshare.task.io.disk.PathHelper;
import com.wedimob.slideshare.task.io.disk.TaskDocumentWriter;
import com.wedimob.slideshare.task.io.network.TaskMediumWriter;

public class TaskDocumentExtractor extends Task<Document, SharedDocument> {

    private Summary summary;
    private WriteType write;

    public TaskDocumentExtractor(PoolExecutor pool, Summary summary,
            Document input, WriteType write, int timeout) {
        super(pool, input, 0, timeout);
        this.write = write;
        if (summary != null)
            this.summary = summary;
        else
            this.summary = new Summary(Factory.buildURL(input, input.baseUri()));
    }

    private static class JSonContainer {
        public JSonSlideshare slideshow;
    }

    private static class JSonSlideshare {
        public String pin_image_url;
        public Integer total_slides;
        public String title;
        public String user_login;
    }

    private JSonContainer extractMetaData(Document doc) {
        String flashPlayer = input.html();
        int beginIdx = flashPlayer.indexOf("slideshare_object = ") + 20;
        int endIdx = flashPlayer.indexOf("; var", beginIdx);
        String flashPlayerJson = flashPlayer.substring(beginIdx, endIdx);
        Gson gson = new Gson();
        return gson.fromJson(flashPlayerJson, JSonContainer.class);
    }

    @Override
    public void run() {
        try {
            JSonContainer json = null;
            if (summary.getSlidenb() == null) {
                if (json == null)
                    json = extractMetaData(input);

                summary.setAuthor(json.slideshow.user_login);
                Element body = input.select("body.smartling-fr").first();
                summary.setCategory(Factory.getElementAttribute(Factory.createDocument(body, input.baseUri()),
                        "li.category", null));
                Medium picture = new Medium(MediumType.PICTURE, "0000", Factory.buildURL(input,
                        json.slideshow.pin_image_url),
                        PathHelper.buildTmpFile("0000.jpeg", summary.getAuthor()));

                summary.setPicture(picture);

                String date = input.select("[name=slideshow_published_time]")
                        .first().attr("content");
                summary.setPublicationDate(Factory.parseCalendar(date));
                summary.setSlidenb(json.slideshow.total_slides);
                summary.setSummary(Factory.getElementAttribute(Factory.createDocument(body, input.baseUri()),
                        "p.descriptionExpanded", null));
                summary.setTitle(json.slideshow.title);
            }
            
            System.err.println("Treat " + summary.getUrl());

            Integer counter = Factory.parseInteger(input.select("strong.h-view-count")
                    .first().text().replace(",", ""));

            // Extract url patterns
            String imagesPatterns = Factory.getElementAttribute(input,
                    "div.playerFacadeImage", "style");

            String nbPageStr = null;

            if (imagesPatterns == null) {
                if (json == null)
                    json = extractMetaData(input);

                imagesPatterns = json.slideshow.pin_image_url;
                imagesPatterns = imagesPatterns.replace("slide-1.",
                        "slide-{PAGE}.");
                nbPageStr = "" + json.slideshow.total_slides;
            }
            imagesPatterns = imagesPatterns.replace("background-image:url('",
                    "");
            imagesPatterns = imagesPatterns.replace("')", "");
            imagesPatterns = imagesPatterns
                    .replace("slide-1-", "slide-{PAGE}-");

            // Extract max page number
            if (nbPageStr == null)
                nbPageStr = Factory.getElementAttribute(input, "label.goToSlideLabel",
                        null);
            Integer nbPages = Factory.parseInteger(nbPageStr);

            List<Medium> pictures = new ArrayList<Medium>();

            for (int i = 1; i < nbPages + 1; i++) {
                String url = new String(imagesPatterns);
                URL mediumURL = Factory.buildURL(input, url.replace("{PAGE}", "" + i));
                URI mediumURI = PathHelper.buildTmpFile(Task.decFormat.format(i) + ".jpeg", summary.getAuthor(), summary.getTitle());
                Medium picture = new Medium(MediumType.PICTURE, decFormat.format(i), mediumURL, mediumURI);
                pictures.add(picture);

                if (write != WriteType.NONE)
                    pool.execAsync(new TaskMediumWriter(pool, picture, timeout));
            }

            /*
            Element element = input.select("li.relatedContent").first();

            element = input.select("li.moreContent").first();
            */

            output = new SharedDocument(summary);
            output.setNbViews(counter);
            for (Medium picture : pictures)
                output.addMedium(picture);

            pool.getResults().putResult(output);

            if (write != WriteType.NONE) {
                pool.execAsync(new TaskDocumentWriter(pool, output, write, timeout));
            }

        } catch (Exception e) {
            e.printStackTrace();
            this.e = e;
        }
    }

}
